package com.xiaoge.springmybatis.springintegrationmybatis;

import com.xiaoge.springmybatis.annotation.XiaogeScan;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;

import java.beans.Introspector;
import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * TODO 该类通过 import 注解导入, 它会去执行 该类下面的方法, 原因可以去看@Import注解源码
 *
 * @author <a href="mailto:1330137071@qq.com">Zhang Xiao</a>
 * @since
 */
public class XiaogeBeanDefinitionRegister implements ImportBeanDefinitionRegistrar {

	@Override
	public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry, BeanNameGenerator importBeanNameGenerator) {
		// 获取我们扫描注解上面的路径
		Map<String, Object> annotationAttributes = importingClassMetadata.getAnnotationAttributes(XiaogeScan.class.getName());
		String path = (String) annotationAttributes.get("value");

		// 扫描
		List<Class> mappers = new ArrayList<>();
		doScan(path, mappers);

		mappers.forEach(mapper -> {
			BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition();
			AbstractBeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();

			// 给构造方法添加参数
			beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(mapper);  // new SpringIntegrationMybatisTwo(mapper)
			// 设置类型
			beanDefinition.setBeanClass(SpringIntegrationMybatisTwo.class);

			// 注册BeanDefinition  (beanName是根据spring源码用到的方法生成的)
			registry.registerBeanDefinition(Introspector.decapitalize(mapper.getSimpleName()), beanDefinition);

		});
	}

	/**
	 * 扫描当前包下所有带@Mapper注解的接口
	 */
	private void doScan(String path, List<Class> mappers) {

		// 获取路径
		path = path.replace(".", "/");

		// 获取资源路径
		ClassLoader classLoader = XiaogeBeanDefinitionRegister.class.getClassLoader();
		URL resource = classLoader.getResource(path);

		// 拿到当前目录下面所有的文件
		File files = new File(resource.getFile());

		// 当前文件是不是目录
		if (files.isDirectory()) {
			// 获取目录下所有文件
			for (File file : files.listFiles()) {
				// 获取文件绝对路径
				String fileName = file.getAbsolutePath();
				// 获取com->.class结尾的名称
				String className = fileName.substring(fileName.indexOf("com"), fileName.indexOf(".class"));
				// 获取权限定类名
				className = className.replace("\\", ".");

				try {
					// 加载class
					Class<?> clazz = classLoader.loadClass(className);
					mappers.add(clazz);
				} catch (ClassNotFoundException e) {

				}
			}
		}
	}

}
